package fr.miage.course7.app.workdata;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import fr.miage.course7.app.App;
import fr.miage.course7.app.model.Participant;
import fr.miage.course7.app.model.Position;
import fr.miage.course7.app.model.Transmission;
import fr.miage.course7.app.model.Participant.Categorie;

/**
 * Lecteur de code XML au format GPX.
 * @author Jonathan LAMOTTE
 *
 */
public class XMLReader {

  /**
   * Parseur GPX recuperant la liste des bateaux ainsi que leurs transmissions.
   * @param xml : chaine de caractère XML
   */
  public static void parseListeBateaux(final String xml) {
    HashMap<Integer, Participant> liste = new HashMap<Integer, Participant>();
    ArrayList<Position> itineraire = new ArrayList<Position>();
    ArrayList<Position> etapes = new ArrayList<Position>();

    System.out.println(xml);

    try {
      // creation d'une fabrique de documents
      DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
      fabrique.setValidating(false);

      // creation d'un constructeur de documents
      DocumentBuilder constructeur = fabrique.newDocumentBuilder();

      // lecture du contenu d'un fichier XML avec DOM
      Document document = constructeur.parse(
                            new InputSource(new StringReader(xml))
                          );

      //traitement du document
      Element racine = document.getDocumentElement();

      NodeList extensions = racine.getElementsByTagName("extensions")
                                .item(0)
                                .getChildNodes();

      NodeList wpts = racine.getElementsByTagName("wpt");

      for (int i = 0; i < extensions.getLength(); i++) {

        Element element = (Element) extensions.item(i);

        if (element.getNodeName() == "participants") {
            NodeList listeParticipants = element.getChildNodes();

            for (int j = 0; j < listeParticipants.getLength(); j++) {

                Element participant = (Element) listeParticipants.item(j);

                int id = Integer.parseInt(participant.getAttribute("id"));
                Categorie c = Categorie.valueOf(
                                   participant.getAttribute("categorie")
                                               );
                String nomBateau = participant.getAttribute("nomBateau");
                String nomSkipper = participant.getAttribute("nomSkipper");

                Participant p = new Participant(id, c, nomBateau, nomSkipper);

                System.out.println("Ajout du participant " + p);
                liste.put(id, p);
            }
        } else if (element.getNodeName() == "etapes") {
            NodeList listeEtapes = element.getChildNodes();

            for (int j = 0; j < listeEtapes.getLength(); j++) {

                Element etape = (Element) listeEtapes.item(j);

                int lon = Integer.parseInt(etape.getAttribute("lon"));
                int lat = Integer.parseInt(etape.getAttribute("lat"));

                Position p = new Position(lat, lon);

                etapes.add(p);
            }
        } else if (element.getNodeName() == "itineraire") {
            NodeList itineraireXML = element.getChildNodes();

            for (int j = 0; j < itineraireXML.getLength(); j++) {

                Element etape = (Element) itineraireXML.item(j);

                int lon = Integer.parseInt(etape.getAttribute("lon"));
                int lat = Integer.parseInt(etape.getAttribute("lat"));

                Position p = new Position(lat, lon);

                itineraire.add(p);
            }
        }
      }

      for (int i = 0; i < wpts.getLength(); i++) {
        Element wpt = (Element) wpts.item(i);

        int year = 0;
        int month = 0;
        int day = 0;

        int id = 0;
        int etape = 0;

        int latitude = Integer.parseInt(wpt.getAttribute("lat"));
        int longitude = Integer.parseInt(wpt.getAttribute("lon"));

        //Recuperation du name et du time
        NodeList w = wpt.getChildNodes();

        for (int j = 0; j < w.getLength(); j++) {

          Element e2 = (Element) w.item(j);

          if (e2.getNodeName() == "time") {

            year = Integer.parseInt(e2.getAttribute("year"));
            month = Integer.parseInt(e2.getAttribute("month"));
            day = Integer.parseInt(e2.getAttribute("day"));

          } else if (e2.getNodeName() == "name") {
            id = Integer.parseInt(e2.getTextContent());

          } else if (e2.getNodeName() == "etape") {
            etape = Integer.parseInt(e2.getTextContent());
          }
        }
        System.out.println(id);
        GregorianCalendar date = new GregorianCalendar(year, month, day);
        liste.get(id).nouvelleTransmission(date, latitude, longitude, etape);
      }

    } catch (Exception e) {
      e.printStackTrace();
    }

    App.setListeParticipants(liste.values());
    App.setListeEtapes(etapes);
    App.setItineraire(itineraire);
  }

  /**
   * Parse la chaine XML contenant des transmissions.
   * @param xml : Chaine XML
   */
  public static void parseTransmissions(final String xml) {
    Transmission transmission = null;

    System.out.println(xml);

    try {
      // creation d'une fabrique de documents
      DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
      fabrique.setValidating(false);

      // creation d'un constructeur de documents
      DocumentBuilder constructeur = fabrique.newDocumentBuilder();

      // lecture du contenu d'un fichier XML avec DOM
      Document document = constructeur.parse(
                            new InputSource(new StringReader(xml))
                          );

      // traitement du document
      Element racine = document.getDocumentElement();

      //Gestion de la mise a jour des etapes
      NodeList parts = racine.getElementsByTagName("participant");

      for (int i = 0; i < parts.getLength(); i++) {

          Element part = (Element) parts.item(i);

          int id = Integer.parseInt(part.getAttribute("id"));
          int etape = Integer.parseInt(part.getAttribute("derniereEtape"));

          App.getParticipant(id).setEtape(etape);
      }


      //Gestion des transmissions
      NodeList wpts = racine.getElementsByTagName("wpt");

      for (int i = 0; i < wpts.getLength(); i++) {
          Element wpt = (Element) wpts.item(i);

          int latitude = Integer.parseInt(wpt.getAttribute("lat"));
          int longitude = Integer.parseInt(wpt.getAttribute("lon"));

          int year = 0;
          int month = 0;
          int day = 0;

          int id = 0;

          NodeList nodeList = wpt.getChildNodes();

          for (int j = 0; j < nodeList.getLength(); j++) {
            Element e = (Element) nodeList.item(j);

            if (e.getNodeName() == "time") {

              year = Integer.parseInt(e.getAttribute("year"));
              month = Integer.parseInt(e.getAttribute("month"));
              day = Integer.parseInt(e.getAttribute("day"));

            } else if (e.getNodeName() == "name") {
              id = Integer.parseInt(e.getTextContent());

            }
          }

          GregorianCalendar date = new GregorianCalendar(year, month, day);
          transmission = new Transmission(id, date, latitude, longitude);
          System.out.println(transmission);
          App.getParticipant(id).nouvelleTransmission(transmission);
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}
